package com.sunmouse.toollib.widget.progress;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import com.sunmouse.toollib.R;

/**
 * Created by leiyun on 2018/5/22.
 */
public class RotateBall extends View {

    private Paint mFirPaint;
    private Paint mSecPaint;
    private Paint mThiPaint;
    private Ball mFirBall;
    private Ball mSecBall;
    private Ball mThiBall;
    private AnimatorSet mAnim;
    private int mRoundRadius;
    private int mObsRadius;
    private long mDuration;
    private int centerY;
    private int centerX;
    private int index;


    public RotateBall(Context context) {
        this(context, null, 0);
    }

    public RotateBall(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RotateBall(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RotateBall);
        this.mObsRadius = array.getDimensionPixelSize(R.styleable.RotateBall_rbObsRadius, 10);
        this.mRoundRadius = array.getDimensionPixelSize(R.styleable.RotateBall_rbRoundRadius, 100);
        array.recycle();


        this.mFirBall = new Ball();
        this.mSecBall = new Ball();
        this.mThiBall = new Ball();

        int random = (int) (Math.random() * 10);
        this.index = random >= 7 ? 7 : random;
        this.mFirBall.setColor(randomColor());
        this.mSecBall.setColor(randomColor());
        this.mThiBall.setColor(randomColor());

        this.mFirPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        this.mFirPaint.setColor(mFirBall.getColor());
        this.mSecPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        this.mSecPaint.setColor(mSecBall.getColor());
        this.mThiPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        this.mThiPaint.setColor(mThiBall.getColor());


        this.mDuration = 1000;

        initAnim();
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        //init ball attributes
        super.onSizeChanged(w, h, oldw, oldh);
        centerX = w / 2;
        centerY = h / 2;
        this.mFirBall.setCenterX(centerX - mRoundRadius);
        this.mFirBall.setCenterY(centerY);
        this.mFirBall.setRadius((float) (mObsRadius));
        this.mSecBall.setCenterX(centerX);
        this.mSecBall.setCenterY(centerY);
        this.mSecBall.setRadius((float) (mObsRadius));
        this.mThiBall.setCenterX(centerX + mRoundRadius);
        this.mThiBall.setCenterY(centerY);
        this.mThiBall.setRadius((float) (mObsRadius));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

//        mFirPaint.setColor(mFirBall.getColor());
//        mSecPaint.setColor(mSecBall.getColor());
//        mThiPaint.setColor(mThiBall.getColor());
        canvas.drawCircle(mFirBall.getCenterX(), mFirBall.getCenterY(), mFirBall.getRadius(), mFirPaint);
        canvas.drawCircle(mSecBall.getCenterX(), mSecBall.getCenterY(), mSecBall.getRadius(), mSecPaint);
        canvas.drawCircle(mThiBall.getCenterX(), mThiBall.getCenterY(), mThiBall.getRadius(), mThiPaint);
    }

    /**
     * init anim
     */
    private void initAnim() {
        ObjectAnimator animFir = ObjectAnimator.ofFloat(mFirBall, "translate", -1.0f, 0.0f, 1.0f, 0.0f, -1.0f);
        animFir.setDuration(mDuration);
        animFir.setRepeatCount(ValueAnimator.INFINITE);
        animFir.setRepeatMode(ValueAnimator.RESTART);
        animFir.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mFirBall.setCenterX(centerX + mRoundRadius * i);
                invalidate();
            }
        });
        ObjectAnimator scaleFir = ObjectAnimator.ofFloat(mFirBall, "translate", mObsRadius, 2 * mObsRadius, mObsRadius, 0.5f * mObsRadius, mObsRadius);
        scaleFir.setDuration(mDuration);
        scaleFir.setRepeatCount(ValueAnimator.INFINITE);
        scaleFir.setRepeatMode(ValueAnimator.RESTART);
        scaleFir.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mFirBall.setRadius(i);
                invalidate();
            }
        });

        ObjectAnimator animSec = ObjectAnimator.ofFloat(mSecBall, "translate", 0.0f, 1.0f, 0.0f, -1.0f, 0.0f);
        animSec.setDuration(mDuration);
        animSec.setRepeatCount(ValueAnimator.INFINITE);
        animSec.setRepeatMode(ValueAnimator.RESTART);
        animSec.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mSecBall.setCenterX(centerX + mRoundRadius * i);
                invalidate();
            }
        });
        ObjectAnimator scaleSec = ObjectAnimator.ofFloat(mFirBall, "translate", 2 * mObsRadius, mObsRadius, 0.5f * mObsRadius, mObsRadius, 2.0f * mObsRadius);
        scaleSec.setDuration(mDuration);
        scaleSec.setRepeatCount(ValueAnimator.INFINITE);
        scaleSec.setRepeatMode(ValueAnimator.RESTART);
        scaleSec.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mSecBall.setRadius(i);
                invalidate();
            }
        });
        ObjectAnimator animThi = ObjectAnimator.ofFloat(mThiBall, "translate", 1.0f, 0.0f, -1.0f, 0.0f, 1.0f);
        animThi.setDuration(mDuration);
        animThi.setRepeatCount(ValueAnimator.INFINITE);
        animThi.setRepeatMode(ValueAnimator.RESTART);
        animThi.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mThiBall.setCenterX(centerX + mRoundRadius * i);
                invalidate();

            }
        });

        ObjectAnimator scaleThi = ObjectAnimator.ofFloat(mFirBall, "translate", mObsRadius, 0.5f * mObsRadius, mObsRadius, 2 * mObsRadius, mObsRadius);
        scaleThi.setDuration(mDuration);
        scaleThi.setRepeatCount(ValueAnimator.INFINITE);
        scaleThi.setRepeatMode(ValueAnimator.RESTART);
        scaleThi.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float i = (float) animation.getAnimatedValue();
                mThiBall.setRadius(i);
                invalidate();
            }
        });


        this.mAnim = new AnimatorSet();
        this.mAnim.playTogether(animFir, scaleFir, animSec, scaleSec, animThi, scaleThi);
    }

    /**
     * start
     */
    public void start() {
        if (getVisibility() != VISIBLE) setVisibility(VISIBLE);
        this.mAnim.start();
    }

    /**
     * cancel
     */
    public void cancel() {
        this.mAnim.cancel();
        this.setVisibility(GONE);
    }

    /**
     * random color
     */
    public int randomColor() {

        int color = 0;
        switch (index) {
            case 1:
                color = Color.RED;
                break;
            case 2:
                color = Color.BLACK;
                break;
            case 3:
                color = Color.BLUE;
                break;
            case 4:
                color = Color.GREEN;
                break;
            case 5:
                color = Color.GRAY;
                break;
            case 6:
                color = Color.DKGRAY;
                break;
            case 7:
                color = Color.CYAN;
                break;
            case 8:
                color = Color.YELLOW;
                break;
            case 9:
                color = 0xFFFF33FF;
                break;
            default:
                color = Color.MAGENTA;
                break;
        }
        index++;
        return color;
    }


    /**
     * ball
     */
    class Ball {
        private float radius;
        private float centerX;
        private float centerY;
        private int color;

        public float getRadius() {
            return radius;
        }

        public void setRadius(float radius) {
            this.radius = radius;
        }

        public float getCenterX() {
            return centerX;
        }

        public void setCenterX(float centerX) {
            this.centerX = centerX;
        }

        public float getCenterY() {
            return centerY;
        }

        public void setCenterY(float centerY) {
            this.centerY = centerY;
        }

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
        }
    }
}
